#include <iostream>
#include "llvm/IR/Module.h"
#include "llvm/IR/IRBuilder.h"
//   int add(int a, int b) {
//     return a + b;
//   }


//  LLVM将其表示为AST树:

//        FunctionDecl
//        - Name: add
//        - Parameters:
//           - ParmVarDecl
//              - Name: a
//              - Type: int
//           - ParmVarDecl
//              - Name: b
//              - Type: int
//        - Return Type: int
//        - Body:
//           - ReturnStmt
//              - Expr:
//                 - BinaryOperator
//                    - LHS: DeclRefExpr(a)
//                    - RHS: DeclRefExpr(b)
//                    - Opcode: BO_Add
//                    - Type: int

//将树转化为LLVM IR:
// 创建一个LLVM模块
using namespace llvm;

auto theModule = llvm::make_unique<Module>("my_module", context);

// 创建函数类型
std::vector<Type*> argTypes(2, Type::getInt32Ty(context));
FunctionType* funcType = FunctionType::get(Type::getInt32Ty(context), argTypes, false);

// 在模块中创建函数
auto func = Function::Create(funcType, Function::ExternalLinkage, "add", theModule.get());

// 在函数中创建基本块
auto entryBB = BasicBlock::Create(context, "entry", func);
IRBuilder<> builder(entryBB);

// 为函数添加参数
auto argA = func->args().begin();
argA->setName("a");
auto argB = std::next(argA);
argB->setName("b");

// 在基本块中创建指令
Value* addResult = builder.CreateAdd(argA, argB);

// 创建return语句
IRBuilder.Creat(addResult);

//LLVM IR:

//        define i32 @add(i32 %a, i32 %b) {
//        entry:
//          %addResult = add i32 %a, %b
//          ret i32 %addResult
//        }

